package entity;

/**
 * @Author: wanqian
 * @Date: 2021/2/21 23:57
 */
public class BiSortNode {

    private int value;

    private BiSortNode left;

    private BiSortNode right;

    public BiSortNode(int value) {
        this.value = value;
    }

    public void add(BiSortNode node) {
        if (node.value < this.value) {
            if (left == null) {
                this.left = node;
            } else {
                this.left.add(node);
            }
        } else {
            if (right == null) {
                this.right = node;
            } else {
                this.right.add(node);
            }
        }

        //需要进行左旋转
        if (rightHeight() - leftHeight() > 1) {
            //如果右节点的左子树高度 > 右子树高度
            if (this.right.leftHeight() > this.right.rightHeight()) {
                //右节点进行右旋转
                this.right.rightRotate();
            }
            leftRotate();
        } else if (leftHeight() - rightHeight() > 1) {
            //需要进行右旋转
            //如果左节点的右子树高度大于左子树高度
            if (this.left.rightHeight() > this.left.leftHeight()) {
                //左节点进行左旋转
                this.left.leftRotate();
            }
            rightRotate();
        }
    }

    public int height() {
        return Math.max(leftHeight(), rightHeight()) + 1;
    }

    public int rightHeight() {
        return right == null ? 0 : right.height();
    }

    public int leftHeight() {
        return left == null ? 0 : left.height();
    }

    /**
     * 以当前节点为根节点进行左旋转
     */
    public void leftRotate() {
        BiSortNode newNode = new BiSortNode(value);
        newNode.right = this.right.left;
        newNode.left = this.left;
        this.value = this.right.value;
        this.right = this.right.right;
        this.left = newNode;
    }

//    public void leftRot() {
//        BiSortNode left = this.left;
//        this.left = left.right;
//        left.right = this;
//    }

    public void rightRotate() {
        BiSortNode newNode = new BiSortNode(value);
        newNode.right = this.right;
        newNode.left = this.left.right;
        this.value = this.left.value;
        this.left = this.left.left;
        this.right = newNode;
    }

    public BiSortNode search(int value) {
        if (this.value == value) {
            return this;
        }

        if (value < this.value) {
            if (this.left == null) {
                return null;
            }
            return this.left.search(value);
        } else {
            if (this.right == null) {
                return null;
            }
            return this.right.search(value);
        }
    }

    public BiSortNode searchParent(int value) {
        if ((this.left != null && this.left.value == value)
                || (this.right != null && this.right.value == value)) {
            return this;
        }
        if (value < this.value && this.left != null) {
            return this.left.searchParent(value);
        } else if (value >= this.value && this.right != null) {
            return this.right.searchParent(value);
        } else {
            return null;
        }
    }

    public void infixOrder() {
        if (left != null) {
            left.infixOrder();
        }
        System.out.println(this);

        if (right != null) {
            right.infixOrder();
        }
    }

    public int getValue() {
        return value;
    }

    public void setValue(int value) {
        this.value = value;
    }

    public BiSortNode getLeft() {
        return left;
    }

    public void setLeft(BiSortNode left) {
        this.left = left;
    }

    public BiSortNode getRight() {
        return right;
    }

    public void setRight(BiSortNode right) {
        this.right = right;
    }

    @Override
    public String toString() {
        return "BinarySortNode{" +
                "value=" + value +
                '}';
    }
}
